<?php
/*
 * @Author: CHINAKAIYUAN<sunkaiyuan@namenode.cn>
 * @Date: 2022-02-04 16:53:56
 * @LastEditTime: 2023-10-05 14:55:13
 * @LastEditors: 孙开源 && sunkaiyuan@namenode.cn
 * @Description: 
 */

namespace App\Http\Services\Pro;


use App\Http\Services\Service;
use App\Repositories\CustomerStorageDetailsRepository;
use App\Repositories\OpenCardCraftHistoryRepository;
use App\Repositories\OpenCardDetailsParameterTestingRepository;
use App\Repositories\OpenCardDetailsRepository;
use App\Repositories\OpenCardDetailsSchedulingRepository;
use App\Repositories\OpenCardRepository;
use App\Repositories\ProProcessesPassRepository;
use DB;
use Illuminate\Database\Eloquent\Collection;

/**
 * @property OpenCardRepository $repository 
 * @property OpenCardDetailsRepository $details 
 * @property CustomerStorageDetailsRepository $order 
 * @property OpenCardDetailsParameterTestingRepository $testing 
 * @property OpenCardCraftHistoryRepository $craft_history
 */
class OpenCardService extends Service
    {
    public function boot(
        OpenCardRepository $repository,
        OpenCardDetailsRepository $details,
        CustomerStorageDetailsRepository $order,
        OpenCardDetailsParameterTestingRepository $testing,
        OpenCardCraftHistoryRepository $craft_history
    ) {
        $this->repository    = $repository;
        $this->details       = $details;
        $this->order         = $order;
        $this->testing       = $testing;
        $this->craft_history = $craft_history;
        }

    public function info()
        {
        $this->repository->setRelation(['details' => ['material', 'unit'], 'raws' => ['process', 'point_stick', 'material', 'glue', 'newmaterial'], 'bom']);
        return $this->repository->condition(request())->getOne();
        }

    public function craft()
        {
        $this->repository->setRelation(['raws' => ['process', 'point_stick', 'material', 'glue', 'newmaterial'], 'bom']);
        $gdata = $this->repository->condition(request())->getOne();

        if ($gdata->craft_history->count() > 0) {
            $craft_raws    = $gdata->bom->details()->with(['point_stick', 'material', 'glue'])->get();
            $gdata         = $gdata->toArray();
            $gdata['raws'] = $craft_raws;
            }
        return $gdata;
        }

    public function parameter_testing_list()
        {
        return $this->testing->condition()->getGrid();
        }
    protected function parameter_testing_save()
        {
        $open_card_l_m = $this->details->whereId(request()->open_card_id)->first();
        if (isEmpty($open_card_l_m)) {
            fail("生产单不存在，无法保存");
            }
        $details = request()->details;

        $defult_user_id = auth()->user()?->employee_id;
        $defult_time_at = date("Y-m-d H:i:s");
        $check_time     = $user_id = null;
        $status_id  = 1;
        $test_count = 0;
        array_map(function ($v) use ($defult_user_id, $defult_time_at, &$user_id, &$check_time, &$status_id, &$test_count)
            {
            if (isEmpty($v['testor_id'])) {
                $v['testor_id'] = $defult_user_id;
                }
            if (isEmpty($v['tested_at'])) {
                $v['tested_at'] = $defult_time_at;
                }
            if (isEmpty($v['status_id'])) {
                $v['status_id'] = 1;
                }
            if ($v['status_id'] == -1) {
                $status_id = -1;
                }
            if ($test_count < 1 && !isEmpty($v['value1'])) {
                $test_count = 1;
                }
            if ($test_count < 2 && !isEmpty($v['value2'])) {
                $test_count = 2;
                }
            if ($test_count < 3 && !isEmpty($v['value3'])) {
                $test_count = 3;
                }
            if ($check_time == null)
                $check_time = $v['tested_at'];
            if ($user_id == null)
                $user_id = $v['testor_id'];
            unset($v['_X_ROW_KEY']);
            return $this->testing->autosave($v);
            }, $details);
        $open_card_l_m->teststatus_id = $status_id;
        $open_card_l_m->testcount     = $test_count;
        $open_card_l_m->tested_at     = $check_time;
        $open_card_l_m->testor_id     = $user_id;
        return $open_card_l_m->save();
        }

    public function conditionCode($request)
        {
        if ($request->has("filter")) {
            $filters = $request->filter;
            foreach ($filters ?? [] as $keys => $filter) {
                foreach ($filter ?? [] as $key => $value)
                    if ($key == 'code') {
                        return is_array($value) ? $value['value'] : $value;
                        }
                }
            }
        }
    public function detailinfo()
        {
        $this->details->setRelation([
            'processrename',
            'scheduling' => ['machine'],
            'film_category',
            'craft_category',
            'main'       => [
                'bom'           => ['details' => ['material', 'point_stick', 'glue']],
                'process_route' => ['details' => ['process']]
            ]
        ]);
        $code = $this->conditionCode(request());
        $data = $this->details->where("code", "like", "{$code}%")->getOne();
        if ($data) {
            $data = $data->toArray();
            }
        else {
            fail("该卡不存在！可能已被删除！");
            }
        if (strlen($code) == 12) {
            $data['code']     = $code;
            $data['quantity'] = 0;
            $list             = $this->details->where("code", "like", "{$code}%")->getList();
            $data['wip']      = $list->map(function ($v) use (&$data)
                {
                $wip              = $v->wip->first();
                $data['quantity'] += $wip->faultle_quantity;
                return $wip;
                })->toArray();

            $data['wip'][0]['faultle_quantity'] = $data['quantity'];
            }

        $data['wip'] = array_values(array_filter($data['wip'], fn($v) => $v['is_scrap'] == 0));
        if (count($data['wip']) == 0) {
            fail("此卡已入库，无需再次刷卡");
            }
        if (!in_array($data['process_id'], [3, 5])) {
            foreach ($data['main']['bom']['details'] ?? [] as $key => $v) {
                $data['main']['bom']['details'][$key]['point_stick'] = preg_replace('/(\d+)g/', '', $v['point_stick'] ?? "");
                }
            }
        return $data;
        }
    public function list()
        {
        $data = $this->repository
            ->condition(request())->getGrid();
        return $data;
        }
    public function getRoute($id = null)
        {
        $open_card = $this->details->whereId($id ?? request('id'))->first()->main;
        //流程中

        $route = $open_card->process_route;
        return $route->details()->with(["process" => ["pro_dept"]])->get();

        }
    public function details()
        {
        $data = $this->details->condition(request())->getGrid();
        return $data;
        }
    protected function sort()
        {
        $request       = request();
        $machine_id    = $request->machine_id;
        $open_card_ids = $request->open_card_ids;
        return array_filter($open_card_ids, function ($open_card_id, $index) use ($machine_id)
            {
            $open_card_sort_m = OpenCardDetailsSchedulingRepository::whereId($open_card_id)->first();
            // $open_card_details_m     = $open_card_sort_m->open_card_details;
            // $open_card_m             = $open_card_details_m->main;
            // $open_card_m->machine_id = $open_card_details_m->machine_id = 
            $open_card_sort_m->machine_id = $machine_id;
            $open_card_sort_m->sort       = $index;

            $open_card_sort_m->save();
            // $open_card_m->save();
            // $open_card_details_m->save();
            }, ARRAY_FILTER_USE_BOTH);
        }
    public function order()
        {
        $data = $this->order
            ->whereStatus_id(1)
            ->condition()
            ->getGrid();
        return $data;
        }
    public function printReport()
        {
        // if (request("name") == '合并' || request("name") == '流转卡3' || request("name") == '单缸') { 
        $list = $this->details->whereIn("id", $this->getRequestIds())->get();
        $xml  = [];
        if (request("name") == '合并打印(截图)') {
            $list->filter(function ($v) use (&$xml)
                {
                $v->material;
                $v->customer;
                $v->process_route;
                $v->main;
                $v->creator;
                $v->order;
                $v->order->strip_index;
                $v->order->washed_index;
                $v->order->main;
                $v->order->main->needInspect    = $v->order->main->needInspect == 1 ? "是" : "否";
                $v->order->main->needEndInspect = $v->order->main->needEndInspect == 1 ? "是" : "否";
                $v->talbe_is_sample             = $v->is_sample == 0 ? "大货" : "小样";
                $res['code']                    = $v->main->code;

                $detail = clone $v;
                if ($detail->main->raws->count() == 0) {
                    $detail->main->raws = new Collection(['']);
                    }

                $detail->main->raws->map(function ($vv, $index) use (&$xml, &$res)
                    {
                    if ($vv != '') {
                        $vv->ground_fabric_strage;
                        $vv->glue_storage;
                        $vv->material;
                        $vv->newmaterial;
                        $vv->point_stick;
                        $vv->glue;
                        $res['raw_' . $index . '_material']     = ['name' => $vv->material->name];
                        $res['raw_' . $index . '_process_name'] = ['name' => $vv->process_name];
                        $res['raw_' . $index . '_glue']         = ['name' => $vv->glue->fullname];
                        $res['raw_' . $index . '_point_stick']  = ['name' => $vv->point_stick->name];

                        }
                    });
                foreach ($v->toArray() as $k => $potitem) {
                    $res['talbe_' . $k] = $potitem;
                    }
                $xml[] = $res;
                });
            }
        else if (request("name") == '批量打印') {
            $ids  = $this->details->whereIn("id", $this->getRequestIds())->pluck("main_id");
            $list = $this->details->whereIn("main_id", $ids)->get();
            $list->filter(function ($v) use (&$xml)
                {
                $detail = clone $v;
                if ($detail->main->raws->count() == 0) {
                    $detail->main->raws = new Collection(['']);
                    }
                $v->customer_material = $v->customer_material == 1 ? "是" : "否";

                $v->material;
                $v->customer;
                $v->process_route;
                $v->main;
                $v->creator;
                $v->order;
                $v->order->strip_index;
                $v->order->washed_index;
                $v->order->main;
                $v->order->main->needInspect    = $v->order->main->needInspect == 1 ? "是" : "否";
                $v->order->main->needEndInspect = $v->order->main->needEndInspect == 1 ? "是" : "否";
                $v->talbe_is_sample             = $v->is_sample == 0 ? "大货" : "小样";

                $res = [];
                $k   = 1;
                $detail->main->raws->map(function ($vv) use ($v, &$res, &$k)
                    {
                    $res = array_merge($res, [
                        'ground_fabric_strage' . $k => ['qunatity' => $vv->ground_fabric_strage->quantity],
                        'glue_storage' . $k => ['quantity' => $vv->glue_storage->quantity],
                        'material' . $k => ['fullname' => $vv->material->fullname],
                        'point_stick' . $k => ['name' => $vv->point_stick->name],
                        'glue' . $k => ['fullname' => $vv->glue->fullname],
                        'grade' . $k => $vv->grade,
                        'process_name' . $k => $vv->process_name
                    ]);
                    if ($vv->material->category_id != 273 && $v->customer_material == "是") {
                        $res['material' . $k]['fullname'] = $vv->material->fullname . "(客供)";
                        }
                    $k++;
                    });
                $res['code'] = $v->main->code;
                foreach ($v->toArray() as $key => $potitem) {
                    $res['talbe_' . $key] = $potitem;
                    }
                $xml[] = $res;
                });
            }
        else if (request("name") == '指标标签') {
            $list->filter(function ($v) use (&$xml)
                {
                $v->material;
                $v->customer;
                $v->process_route;
                $v->main;
                $v->creator;
                $v->order;
                $v->order->strip_index;
                $v->order->washed_index;
                $v->order->main;
                $v->order->main->needInspect    = $v->order->main->needInspect == 1 ? "是" : "否";
                $v->order->main->needEndInspect = $v->order->main->needEndInspect == 1 ? "是" : "否";
                $v->talbe_is_sample             = $v->is_sample == 0 ? "大货" : "小样";
                $res['code']                    = $v->main->code;
                foreach ($v->toArray() as $k => $potitem) {
                    $res['talbe_' . $k] = $potitem;
                    }
                $xml[] = $res;
                });
            }
        else {
            $list->filter(function ($v) use (&$xml)
                {
                $detail = clone $v;
                if ($detail->main->raws->count() == 0) {
                    $detail->main->raws = new Collection(['']);
                    }
                $v->customer_material = $v->customer_material == 1 ? "是" : "否";
                $detail->main->raws->map(function ($vv) use ($v, &$xml)
                    {
                    $v->material;

                    $v->customer;
                    $v->process_route;
                    $v->main;
                    $v->creator;
                    $v->order;
                    $v->order->strip_index;
                    $v->order->washed_index;
                    $v->order->main;
                    $v->order->main->needInspect    = $v->order->main->needInspect == 1 ? "是" : "否";
                    $v->order->main->needEndInspect = $v->order->main->needEndInspect == 1 ? "是" : "否";
                    $v->talbe_is_sample             = $v->is_sample == 0 ? "大货" : "小样";
                    if ($vv != '') {
                        $vv->ground_fabric_strage;
                        $vv->glue_storage;
                        $vv->material;

                        if ($vv->material->category_id != 273 && $v->customer_material == "是") {
                            $vv->material->fullname .= "(客供)";
                            }
                        $vv->point_stick;
                        $vv->glue;
                        $vv->newmaterial;
                        $res = $vv->toArray();
                        }
                    $res['code'] = $v['code'];
                    foreach ($v->toArray() as $k => $potitem) {
                        $res['talbe_' . $k] = $potitem;
                        }
                    $xml[] = $res;
                    });
                });
            }
        return createReport($xml);
        }
    protected function synccraft()
        {
        $this->repository->get()->filter(function ($v)
            {
            $raws = $v->raws;

            $craft_remark = $raws->map(fn($vv) => $vv->material?->fullname ?? "")->implode("+");
            $craft_remark .= $v->customer_material == 1 ? "(客供)" : "";

            $v->details->filter(function ($v) use ($craft_remark)
                {
                $order = $v->order;
                if ($order) {
                    $order->craft_remark = $v->craft_remark = $craft_remark;
                    $order->save();
                    }
                $v->save();
                });
            });
        }
    protected function reSetBOM()
        {
        $data            = $this->repository->editgetDataRequest();
        $request         = request()->toArray();
        $data['details'] = array_map(function ($v)
            {
            return $this->details->autosave($v, true, ['scheduling'])->toArray();
            }, $data['details']);
        $gdata           = $this->repository->autosave($data);

        $craft_remark =
            implode("+", array_map(function ($v)
                {
                if (isset($v['material']))
                    return $v['material']['fullname'] ?? "";
                else
                    return "";
                }, $request['raws']));

        $gdata->details->filter(function ($v) use ($gdata, &$key, $craft_remark)
            {
            $v->craft_remark = $v->order->craft_remark = $craft_remark . $v->backing_category_color . ($gdata->customer_material == 1 ? "(客供)" : "");
            $order = $v->order;
            if ($order) {
                $order->craft_remark = $v->craft_remark;
                $order->save();
                }
            $v->save();
            });
        $this->repository->createDeailsStorage($gdata, false);
        }
    protected function save()
        {
        $data               = $this->repository->getDataRequest();
        $request            = request()->toArray();
        $data['details']    = array_map(function ($v)
            {
            $buf               = $this->details->initializeFieldsData($v);
            $buf['scheduling'] = $v['scheduling'];
            return $this->details->autosave($buf, true, ['scheduling'])->toArray();
            }, $data['details']);
        $data['machine_id'] = 0;

        $gdata = $this->repository->autosave($data);

        $craft_remark =
            implode("+", array_map(function ($v)
                {
                if (isset($v['material']))
                    return $v['material']['fullname'] ?? "";
                else
                    return "";
                }, $request['raws']));
        if ($gdata->status_id != 0) {
            fail("{$gdata->code}状态{$gdata->status->name},修改失败！");
            }
        $key = 1;
        $gdata->details->filter(function ($v) use ($gdata, &$key, $craft_remark)
            {
            $order                = $v->order;
            $order->open_quantity = $order->open_card->sum("quantity");
            if ($v->quantity <= 0) {
                fail("开卡数不能为0！");
                }
            $order->lack_quantity = $order->quantity - $order->open_quantity;
            $v->machine_id        = $gdata->machine_id;
            $v->craft_remark      = $order->craft_remark = isEmpty($craft_remark) ? $v->craft_remark : ($craft_remark . $v->backing_category_color . ($gdata->customer_material == 1 ? "(客供)" : ""));

            $order->save();
            $v->code             = $gdata->code . substr("00" . ($key++), -2, 2);
            $v->needInspect      = $gdata->needInspect ?? 0;
            $v->needEndInspect   = $gdata->needEndInspect ?? 0;
            $v->process_route_id = $gdata->process_route_id;
            $v->machine_id       = $gdata->machine_id;
            //新增后，直接创建虚拟库存
            $v->process_id      = 10;
            $v->process_pass_id = ProProcessesPassRepository::run('init', [$v])->id;

            $v->save();
            });
        $this->repository->createDeailsStorage($gdata);
        }

    protected function repair()
        {
        return $this->details->whereIn("id", $ids ?? $this->getRequestIds())->get()->filter(function ($v)
            {

            if ($v->process_id == 0 || $v->process_id == null) {
                $v->process_id      = 10;
                $v->process_pass_id = ProProcessesPassRepository::run('init', [$v])->id;
                $v->save();
                }
            });

        }
    protected function saveroll()
        {
        $request = request();
        $data    = [
            'id'                      => $request->id,
            'roll_quantity'           => $request->roll_quantity,
            'roll_auxiliary_quantity' => $request->roll_auxiliary_quantity,
            'remark'                  => $request->remark,
        ];
        return $this->details->autosave($data);
        }
    protected function delete($ids = null)
        {
        return $this->repository->whereIn("id", $ids ?? $this->getRequestIds())->get()->filter(function ($v)
            {


            $this->repository->nocreateDeailsStorage($v);
            $v->details->filter(function ($vv)
                {

                if ($vv->process_id != 10) {
                    fail("流转卡已【{$vv->process->name}】,操作失败！");
                    }
                //删除刷卡
                $vv->process_pass->filter(fn($v) => $v->delete());
                //删除虚拟库存
                $vv->wip->filter(fn($v) => $v->delete());

                $order = $vv->order;
                $vv->delete();
                $order->open_quantity = $order->open_card->sum("quantity");
                $order->lack_quantity = $order->quantity - $order->open_quantity;
                $order->save();
                });

            $v->raws->filter(function ($vv)
                {
                $vv->delete();
                });
            $v->delete();
            });
        }
    protected function deleteItem()
        {
        return $this->delete($this->getMain());
        }
    private function getMain()
        {
        return $this->details->whereIn("id", $this->getRequestIds())->get()->pluck("main_id");
        }
    protected function audit($ids = null)
        {
        return $this->repository->whereIn("id", $ids ?? $this->getRequestIds())->get()->filter(function ($v)
            {
            auditSave($v);
            $this->repository->createDeailsStorage($v);
            });
        }
    protected function auditItem()
        {
        return $this->audit($this->getMain());
        }
    protected function setCraft()
        {
        $request = request();
        $gdata   = $this->details->whereId($request->id)->first();
        if (isEmpty($request->bom_id)) {
            fail("新工艺必须选择！");
            }
        if ($gdata) {
            $open_card_m         = $this->repository->whereId($gdata->main_id)->first();
            $open_card_m->bom_id = $request->bom_id;
            $open_card_m->save();

            return $this->craft_history->create([
                'open_card_id'  => $open_card_m->id,
                'history_craft' => $request->history_craft,
                'new_craft'     => $request->new_craft,
            ]);
            }
        else {
            fail('流转明细不存在！');
            }
        }
    public function craft_list()
        {
        return $this->craft_history->condition()->getGrid();
        }

    /**
     * 作废状态
     */
    public function cancel()
        {
        $request = request();
        $ids     = $request->ids;

        $rows = $this->details->whereIn("id", $ids)->get();

        foreach ($rows as $row) {

            if ($row->is_cancel == 1) {
                $row->is_cancel      = $row->order->is_cancel = 0;
                $row->is_cancel_by   = $row->order->is_cancel_by = null;
                $row->is_cancel_date = $row->order->is_cancel_date = null;
                }
            else {
                $row->is_cancel      = $row->order->is_cancel = 1;
                $row->is_cancel_by   = $row->order->is_cancel_by = $request->user()->name;
                $row->is_cancel_date = $row->order->is_cancel_date = date('Y-m-d H:i:s');
                }

            $row->order->save();
            $row->save();
            }
        }
    }